package br.edu.univas.locadoragraph.dao;


import java.util.ArrayList;
import java.util.List;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.index.Index;

import br.edu.univas.locadoragraph.database.Connection;
import br.edu.univas.locadoragraph.database.Keys;
import br.edu.univas.locadoragraph.to.ActorTO;

public class ActorDAO {
	
	private Connection conn;

	public ActorDAO() {
		conn = Connection.getInstance();
	}
	
	public boolean saveActorGraph(ActorTO actor){
		System.out.println("Method: saveActorGraph");
		long start = System.currentTimeMillis();
		GraphDatabaseService graph = conn.newGraphDatabase();
		
		Index<Node> index = graph.index().forNodes(Keys.INDEXACTOR);
		Node node = index.get(Keys.ACTORKEY, actor.getName().toLowerCase()).getSingle();
		
		if (node == null) {
			Transaction tx = graph.beginTx();
			
			try {
				node = graph.createNode();
				node.setProperty(Keys.ACTORKEY, actor.getName().toLowerCase());
				node.setProperty("gender", actor.getGender().toLowerCase());
				index.add(node, Keys.ACTORKEY, actor.getName().toLowerCase());
				tx.success();
				tx.finish();
				//graph.shutdown();
				double total = (System.currentTimeMillis() - start);
				System.out.println("Actor saved! Time: " + total / 1000);
				return true;
			} catch (Exception e) {
				System.out.println("Erro" + e);
				tx.failure();
				tx.finish();
			}
		}
		//graph.shutdown();
		double total = (System.currentTimeMillis() - start);
		System.out.println("Actor not saved! Time: " + total /1000);
		return false;
	}
	
	public List<String> getAllActors(){
		System.out.println("Method: getAllActors");
		List<String> actors = new ArrayList<String>();
		long start = System.currentTimeMillis();
		GraphDatabaseService graph = conn.newGraphDatabase();
		for (Node node : getNodesActor(graph)) {
	
			actors.add((String) node.getProperty(Keys.ACTORKEY));			
		}
		//graph.shutdown();
		double total = System.currentTimeMillis() - start;
		System.out.println("Time: " + total/1000 );
		return actors;
	}

	public List<ActorTO> getListActorsTable() {
		System.out.println("Method: getListActorsTable");
		List<ActorTO> actors = new ArrayList<ActorTO>();
		long start = System.currentTimeMillis();
		GraphDatabaseService graph = conn.newGraphDatabase();
		for (Node node : getNodesActor(graph)) {
			System.out.println("Node: " + node);
			ActorTO actor = new ActorTO();
			actor.setName((String) node.getProperty(Keys.ACTORKEY));
			actor.setGender((String) node.getProperty("gender"));
			actors.add(actor);
		}
		//graph.shutdown();
		double total = System.currentTimeMillis() - start;
		System.out.println("Time: " + total/1000);
		return actors;
	}

	public boolean updateActorGraph(ActorTO actor, String key) {
		  GraphDatabaseService graph = conn.newGraphDatabase();
		  Node node = getNodeActor(graph, key.toLowerCase());
		  
		  if (node != null) {
			Transaction tx = graph.beginTx();
			try {
				node.setProperty(Keys.ACTORKEY, actor.getName().toLowerCase());
				node.setProperty("gender", actor.getGender().toLowerCase());
				
				tx.success();
				tx.finish();
				return true;
			} catch (Exception e) {
				tx.failure();
				tx.finish();
				System.err.println("Erro: " + e );
			}
			
		}
		return true;
	}

	private Iterable<Node> getNodesActor(GraphDatabaseService graph){
		Index<Node> index = graph.index().forNodes(Keys.INDEXACTOR);
		Iterable<Node> nodes = index.query(Keys.ACTORKEY, "*");
		return nodes;
	}
	
	public Node getNodeActor(GraphDatabaseService graph, String actor){
		Index<Node> index = graph.index().forNodes(Keys.INDEXACTOR);
		Node node = index.get(Keys.ACTORKEY, actor.toLowerCase()).getSingle();
		return node;
	}
}